#include <stdio.h>
#include <string.h>
#include <dos.h>
#include "mpx_supt.h"
#include "dcb.h"

#define P_MSK 0x21

unsigned char inportp(int port_id);
void outportb(int port_id, unsigned char value);
void enable(void);
void disable(void);
void interrupt(*getvect(int int_ID))(void);
void setvect(int int_ID, void interrupt(*handler)(void));

int com_open(int *eflag_p, int baud_rate);
int com_close(void);
int com_read(char *buf_p, int *count_p);
int com_write(char *buf_p, int *count_p);

//void interrupt name();
//void name();

int com_open(int *eflag_p, int baud_rate)
{
	//enable();
	
	if(eflag_p == NULL)
		return -101;
	if(baud_rate <= 0)
		return -102;
	if(flag = OPEN)
		return -103;
	else
	{    /* DCB initializtion */  
		int baud_rate_devisor;

	   mpx_dcb* pDCB;
	   pDCB->state = IDLE;
           pDCB->flag = OPEN;
           pDCB->e_flag = eflag_p; 
		
	   oldHandler = getvect( );
	   setvect (  &detectHandler);

		baud_rate_divisor = 115200 / (long) baud_rate;
		outportb(COM1_LC, 0x80);
		outportb(COM1_BAUD_RATE_DIVISOR_LSB ,baud_rate_divisor & 0xFF);
		outportb(COM1_LC, 0x03);

		disable();
		int mask = inportb(P_MSK);
		mask = mask & ~0x10;
		outportb(P_MSK, mask);
		enable();
		//store 0x08 in modem control register to enable serial interrupt
		//store 0x01 in the interrupt enable register to enable input ready interrupts
		return 0;
	}
}

int com_close(void)
{
	if(flag != OPEN)
	{
		return -201;
	}
	else
	{
		disable();
		mask = inportb(P_MSK);
		mask = mask | 0x10;
		outportb(P_MSK, mask);
		enable();
		//load 0x00 into modem status and interrupt inable registers, disable ACC interrupts
		//restore original interrupts using setvect()

		return 0;
	}
}

int com_read(char *buf_p, int *count_p)
{
	char a[count_p +1];
	a = gets(*buf_p);

	if(flag != OPEN)
	{
		return -301;
	}

	if(buf_p == NULL)
	{
		return -302;
	}

	if(count_p == NULL)
	{
		return -303;
	}
	if(state != IDLE)
	{
		return -304;
	}
	else
	{
		DCB.inputbuffer = buf_p;
		DCB.inputcount = count_p;
		DEB.inputdone = 0;
		eflag_p = 0;
		state = READ;
		//get chars from ring buffer
		//re-enable interrupts

		if(dcb.inputdone < dcb.inputcount)
		{
			return 0;
			state = READ;
			com_read( , count_p + 1);
		}

		if *(dcb.inputbuff-1 == '\r')
		{
			dcb.inputbuff-1 = '\0';
		}

		else
			dcb.inputbuf = '\0';

		state = IDLE;
		eflag_p = 0;
		inputcount = inputdone;
	}
}

int com_write(char *buf_p, int *count_p)
{
	char a[countp+1];
	a = puts(*buf_p);

	if(flag != OPEN)
	{
		return -401;
	}

	if(buf_p == NULL)
	{
		return -402;
	}

	if(count_p == NULL)
	{
		return -403;
	}
	if(state != IDLE)
	{
		return -404;
	}
	else
	{
		Dcb->outputbuff = buffer;
		Dcb->outputcount = count;
		Dcb->outpudone = 0;

		state = WRITE;
		eflag_p = 0;
		outportb(COM1_BASE, *DCB.outputbuff);

		outputbuff++;
		outputdone++;
		int mask = inportb(COM1_INT_EN);
		mask = mask | 0x02;
		outportb(COM1_INT_EN,mask);

		return 0;
	}
}
